0%

Hexo系列 - Next个性化配置

看着别人的Next 主题炫酷的很,自己的很low,怎么办。不慌盘它

版本

  • Hexo 版本:5.0.x
  • Next 版本:7.8.0

如果和以上版本不同,请参考具体版本配置

鼠标点击特效

有以下三种特效爱心特效 礼花特效 爆炸特性
themes/next/source/js/文件夹下新建cursor文件夹

爱心特效

新建文件love.min.js,将以下代码复制到文件,将js文件复制到themes/next/source/js/cursor/文件夹

1
!function(e,t,a){function n(){c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){for(var e=0;e<d.length;e++)d[e].alpha<=0?(t.body.removeChild(d[e].el),d.splice(e,1)):(d[e].y--,d[e].scale+=.004,d[e].alpha-=.013,d[e].el.style.cssText="left:"+d[e].x+"px;top:"+d[e].y+"px;opacity:"+d[e].alpha+";transform:scale("+d[e].scale+","+d[e].scale+") rotate(45deg);background:"+d[e].color+";z-index:99999");requestAnimationFrame(r)}function o(){var t="function"==typeof e.onclick&&e.onclick;e.onclick=function(e){t&&t(),i(e)}}function i(e){var a=t.createElement("div");a.className="heart",d.push({el:a,x:e.clientX-5,y:e.clientY-5,scale:1,alpha:1,color:s()}),t.body.appendChild(a)}function c(e){var a=t.createElement("style");a.type="text/css";try{a.appendChild(t.createTextNode(e))}catch(t){a.styleSheet.cssText=e}t.getElementsByTagName("head")[0].appendChild(a)}function s(){return"rgb("+~~(255*Math.random())+","+~~(255*Math.random())+","+~~(255*Math.random())+")"}var d=[];e.requestAnimationFrame=function(){return e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)}}(),n()}(window,document);

礼花特效

新建文件fireworks.js,将以下代码复制到文件,将js文件复制到themes/next/source/js/cursor/文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
class Circle {
constructor({ origin, speed, color, angle, context }) {
this.origin = origin
this.position = { ...this.origin }
this.color = color
this.speed = speed
this.angle = angle
this.context = context
this.renderCount = 0
}

draw() {
this.context.fillStyle = this.color
this.context.beginPath()
this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
this.context.fill()
}

move() {
this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
this.renderCount++
}
}

class Boom {
constructor ({ origin, context, circleCount = 16, area }) {
this.origin = origin
this.context = context
this.circleCount = circleCount
this.area = area
this.stop = false
this.circles = []
}

randomArray(range) {
const length = range.length
const randomIndex = Math.floor(length * Math.random())
return range[randomIndex]
}

randomColor() {
const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
}

randomRange(start, end) {
return (end - start) * Math.random() + start
}

init() {
for(let i = 0; i < this.circleCount; i++) {
const circle = new Circle({
context: this.context,
origin: this.origin,
color: this.randomColor(),
angle: this.randomRange(Math.PI - 1, Math.PI + 1),
speed: this.randomRange(1, 6)
})
this.circles.push(circle)
}
}

move() {
this.circles.forEach((circle, index) => {
if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
return this.circles.splice(index, 1)
}
circle.move()
})
if (this.circles.length == 0) {
this.stop = true
}
}

draw() {
this.circles.forEach(circle => circle.draw())
}
}

class CursorSpecialEffects {
constructor() {
this.computerCanvas = document.createElement('canvas')
this.renderCanvas = document.createElement('canvas')

this.computerContext = this.computerCanvas.getContext('2d')
this.renderContext = this.renderCanvas.getContext('2d')

this.globalWidth = window.innerWidth
this.globalHeight = window.innerHeight

this.booms = []
this.running = false
}

handleMouseDown(e) {
const boom = new Boom({
origin: { x: e.clientX, y: e.clientY },
context: this.computerContext,
area: {
width: this.globalWidth,
height: this.globalHeight
}
})
boom.init()
this.booms.push(boom)
this.running || this.run()
}

handlePageHide() {
this.booms = []
this.running = false
}

init() {
const style = this.renderCanvas.style
style.position = 'fixed'
style.top = style.left = 0
style.zIndex = '999999999999999999999999999999999999999999'
style.pointerEvents = 'none'

style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight

document.body.append(this.renderCanvas)

window.addEventListener('mousedown', this.handleMouseDown.bind(this))
window.addEventListener('pagehide', this.handlePageHide.bind(this))
}

run() {
this.running = true
if (this.booms.length == 0) {
return this.running = false
}

requestAnimationFrame(this.run.bind(this))

this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)

this.booms.forEach((boom, index) => {
if (boom.stop) {
return this.booms.splice(index, 1)
}
boom.move()
boom.draw()
})
this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
}
}

const cursorSpecialEffects = new CursorSpecialEffects()
cursorSpecialEffects.init()

爆炸特效

新建文件explosion.min.js,将以下代码复制到文件,将js文件复制到themes/next/source/js/cursor/文件夹

1
"use strict";function updateCoords(e){pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){var a={};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){var a={};return a.x=e,a.y=t,a.color="#F00",a.radius=0.1,a.alpha=0.5,a.lineWidth=6,a.draw=function(){ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){for(var t=0;t<e.animatables.length;t++){e.animatables[t].target.draw()}}function animateParticules(e,t){for(var a=createCircle(e,t),n=[],i=0;i<numberOfParticules;i++){n.push(createParticule(e,t))}anime.timeline().add({targets:n,x:function(e){return e.endPos.x},y:function(e){return e.endPos.y},radius:0.1,duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule}).add({targets:a,radius:anime.random(80,160),lineWidth:0,alpha:{value:0,easing:"linear",duration:anime.random(600,800)},duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule,offset:0})}function debounce(e,t){var a;return function(){var n=this,i=arguments;clearTimeout(a),a=setTimeout(function(){e.apply(n,i)},t)}}var canvasEl=document.querySelector(".fireworks");if(canvasEl){var ctx=canvasEl.getContext("2d"),numberOfParticules=30,pointerX=0,pointerY=0,tap="mousedown",colors=["#FF1461","#18FF92","#5A87FF","#FBF38C"],setCanvasSize=debounce(function(){canvasEl.width=2*window.innerWidth,canvasEl.height=2*window.innerHeight,canvasEl.style.width=window.innerWidth+"px",canvasEl.style.height=window.innerHeight+"px",canvasEl.getContext("2d").scale(2,2)},500),render=anime({duration:1/0,update:function(){ctx.clearRect(0,0,canvasEl.width,canvasEl.height)}});document.addEventListener(tap,function(e){"sidebar"!==e.target.id&&"toggle-sidebar"!==e.target.id&&"A"!==e.target.nodeName&&"IMG"!==e.target.nodeName&&(render.play(),updateCoords(e),animateParticules(pointerX,pointerY))},!1),setCanvasSize(),window.addEventListener("resize",setCanvasSize,!1)}"use strict";function updateCoords(e){pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){var a={};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){var a={};return a.x=e,a.y=t,a.color="#F00",a.radius=0.1,a.alpha=0.5,a.lineWidth=6,a.draw=function(){ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){for(var t=0;t<e.animatables.length;t++){e.animatables[t].target.draw()}}function animateParticules(e,t){for(var a=createCircle(e,t),n=[],i=0;i<numberOfParticules;i++){n.push(createParticule(e,t))}anime.timeline().add({targets:n,x:function(e){return e.endPos.x},y:function(e){return e.endPos.y},radius:0.1,duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule}).add({targets:a,radius:anime.random(80,160),lineWidth:0,alpha:{value:0,easing:"linear",duration:anime.random(600,800)},duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule,offset:0})}function debounce(e,t){var a;return function(){var n=this,i=arguments;clearTimeout(a),a=setTimeout(function(){e.apply(n,i)},t)}}var canvasEl=document.querySelector(".fireworks");if(canvasEl){var ctx=canvasEl.getContext("2d"),numberOfParticules=30,pointerX=0,pointerY=0,tap="mousedown",colors=["#FF1461","#18FF92","#5A87FF","#FBF38C"],setCanvasSize=debounce(function(){canvasEl.width=2*window.innerWidth,canvasEl.height=2*window.innerHeight,canvasEl.style.width=window.innerWidth+"px",canvasEl.style.height=window.innerHeight+"px",canvasEl.getContext("2d").scale(2,2)},500),render=anime({duration:1/0,update:function(){ctx.clearRect(0,0,canvasEl.width,canvasEl.height)}});document.addEventListener(tap,function(e){"sidebar"!==e.target.id&&"toggle-sidebar"!==e.target.id&&"A"!==e.target.nodeName&&"IMG"!==e.target.nodeName&&(render.play(),updateCoords(e),animateParticules(pointerX,pointerY))},!1),setCanvasSize(),window.addEventListener("resize",setCanvasSize,!1)};

配置

themes/next/layout/文件夹下新建_custom文件夹
themes/next/layout/_custom/文件夹下新建custom.swig文件,将以下代码复制到文件

1
2
3
4
5
6
7
8
9
10
11
{% if theme.cursor_effect %}
{% if theme.cursor_effect.type == "fireworks" %}
<script src="/js/cursor/fireworks.js"></script>
{% elseif theme.cursor_effect.type == "explosion" %}
<canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas>
<script src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
<script src="/js/cursor/explosion.min.js"></script>
{% elseif theme.cursor_effect.type == "love" %}
<script src="/js/cursor/love.min.js"></script>
{% endif %}
{% endif %}

启用

添加以下配置到Next _config.yml 配置文件

1
2
3
4
# 点击特效
cursor_effect:
enabled: true
type: love # fireworks:礼花 | explosion:爆炸 | love:浮出爱心

设置背景动画

next 有自带的背景动画,在以下配置中开启开关。在three_waves canvas_lines canvas_sphere三个配置中开启其中一种背景

1
2
3
4
5
6
# 设置「背景动画」
three:
enable: true #开关
three_waves: false
canvas_lines: false
canvas_sphere: true

找到以下配置,打开注释即可使用

1
2
3
4
5
6
vendors:
# Internal version: 1.0.0
three: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/three.min.js
three_waves: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/three-waves.min.js
canvas_lines: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/canvas_lines.min.js
canvas_sphere: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/canvas_sphere.min.js

设置背景彩带

找到以下配置,开启配置开关。

1
2
3
4
5
6
#设置canvas背景彩带
canvas_ribbon:
enable: true
size: 90 # The width of the ribbon
alpha: 0.6 # The transparency of the ribbon
zIndex: -1 # The display level of the ribbon

找到以下配置,这是next 自带的点击生成彩带js,可以打开注释,自己先试一下效果。
但是我们需要设置 随机生成的动画彩带效果

1
2
3
vendors:
# Internal version: 1.0.0
# canvas_ribbon: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-ribbon@1/canvas-ribbon.js

themes/next/source/js/文件夹下新建ribbon文件夹
新建文件ribbon.js,将以下代码复制到文件。将js文件复制到themes/next/source/js/ribbon/文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
/**
* Ribbons Class File.
* Creates low-poly ribbons background effect inside a target container.
*/
(function (name, factory)
{
if (typeof window === "object")
{
window[name] = factory();
}

})("Ribbons", function ()
{
var _w = window,
_b = document.body,//返回html dom中的body节点 即<body>
_d = document.documentElement;//返回html dom中的root 节点 即<html>

// random helper
var random = function ()
{
if (arguments.length === 1) // only 1 argument
{
if (Array.isArray(arguments[0])) // extract index from array
{
var index = Math.round(random(0, arguments[0].length - 1));
return arguments[0][index];
}
return random(0, arguments[0]); // assume numeric
} else
if (arguments.length === 2) // two arguments range
{
return Math.random() * (arguments[1] - arguments[0]) + arguments[0];
}
return 0; // default
};

// screen helper
var screenInfo = function (e)
{
var width = Math.max(0, _w.innerWidth || _d.clientWidth || _b.clientWidth || 0),
height = Math.max(0, _w.innerHeight || _d.clientHeight || _b.clientHeight || 0),
scrollx = Math.max(0, _w.pageXOffset || _d.scrollLeft || _b.scrollLeft || 0) - (_d.clientLeft || 0),
scrolly = Math.max(0, _w.pageYOffset || _d.scrollTop || _b.scrollTop || 0) - (_d.clientTop || 0);

return {
width: width,
height: height,
ratio: width / height,
centerx: width / 2,
centery: height / 2,
scrollx: scrollx,
scrolly: scrolly };

};

// mouse/input helper
var mouseInfo = function (e)
{
var screen = screenInfo(e),
mousex = e ? Math.max(0, e.pageX || e.clientX || 0) : 0,
mousey = e ? Math.max(0, e.pageY || e.clientY || 0) : 0;

return {
mousex: mousex,
mousey: mousey,
centerx: mousex - screen.width / 2,
centery: mousey - screen.height / 2 };

};

// point object
var Point = function (x, y)
{
this.x = 0;
this.y = 0;
this.set(x, y);
};
Point.prototype = {
constructor: Point,

set: function (x, y)
{
this.x = x || 0;
this.y = y || 0;
},
copy: function (point)
{
this.x = point.x || 0;
this.y = point.y || 0;
return this;
},
multiply: function (x, y)
{
this.x *= x || 1;
this.y *= y || 1;
return this;
},
divide: function (x, y)
{
this.x /= x || 1;
this.y /= y || 1;
return this;
},
add: function (x, y)
{
this.x += x || 0;
this.y += y || 0;
return this;
},
subtract: function (x, y)
{
this.x -= x || 0;
this.y -= y || 0;
return this;
},
clampX: function (min, max)
{
this.x = Math.max(min, Math.min(this.x, max));
return this;
},
clampY: function (min, max)
{
this.y = Math.max(min, Math.min(this.y, max));
return this;
},
flipX: function ()
{
this.x *= -1;
return this;
},
flipY: function ()
{
this.y *= -1;
return this;
} };


// class constructor
var Factory = function (options)
{
this._canvas = null;
this._context = null;
this._sto = null;
this._width = 0;
this._height = 0;
this._scroll = 0;
this._ribbons = [];
this._options = {
// ribbon color HSL saturation amount
colorSaturation: "80%",
// ribbon color HSL brightness amount
colorBrightness: "60%",
// ribbon color opacity amount
colorAlpha: 0.65,
// how fast to cycle through colors in the HSL color space
colorCycleSpeed: 6,
// where to start from on the Y axis on each side (top|min, middle|center, bottom|max, random)
verticalPosition: "center",
// how fast to get to the other side of the screen
horizontalSpeed: 200,
// how many ribbons to keep on screen at any given time
ribbonCount: 3,
// add stroke along with ribbon fill colors
strokeSize: 0,
// move ribbons vertically by a factor on page scroll
parallaxAmount: -0.5,
// add animation effect to each ribbon section over time
animateSections: true };

this._onDraw = this._onDraw.bind(this);
this._onResize = this._onResize.bind(this);
this._onScroll = this._onScroll.bind(this);
this.setOptions(options);
this.init();
};

// class prototype
Factory.prototype = {
constructor: Factory,

// Set and merge local options
setOptions: function (options)
{
if (typeof options === "object")
{
for (var key in options)
{
if (options.hasOwnProperty(key))
{
this._options[key] = options[key];
}
}
}
},

// Initialize the ribbons effect
init: function ()
{
try
{
this._canvas = document.createElement("canvas");
this._canvas.style["display"] = "block";
this._canvas.style["position"] = "fixed";
this._canvas.style["margin"] = "0";
this._canvas.style["padding"] = "0";
this._canvas.style["border"] = "0";
this._canvas.style["outline"] = "0";
this._canvas.style["left"] = "0";
this._canvas.style["top"] = "0";
this._canvas.style["width"] = "100%";
this._canvas.style["height"] = "100%";
this._canvas.style["z-index"] = "-1";
this._canvas.style["background-color"]="#1f1f1f";
this._canvas.id = "bgCanvas";
this._onResize();

this._context = this._canvas.getContext("2d");
this._context.clearRect(0, 0, this._width, this._height);
this._context.globalAlpha = this._options.colorAlpha;

window.addEventListener("resize", this._onResize);
window.addEventListener("scroll", this._onScroll);
document.body.appendChild(this._canvas);
}
catch (e) {
console.warn("Canvas Context Error: " + e.toString());
return;
}
this._onDraw();
},

// Create a new random ribbon and to the list
addRibbon: function ()
{
// movement data
var dir = Math.round(random(1, 9)) > 5 ? "right" : "left",
stop = 1000,
hide = 200,
min = 0 - hide,
max = this._width + hide,
movex = 0,
movey = 0,
startx = dir === "right" ? min : max,
starty = Math.round(random(0, this._height));

// asjust starty based on options
if (/^(top|min)$/i.test(this._options.verticalPosition))
{
starty = 0 + hide;
} else
if (/^(middle|center)$/i.test(this._options.verticalPosition))
{
starty = this._height / 2;
} else
if (/^(bottom|max)$/i.test(this._options.verticalPosition))
{
starty = this._height - hide;
}

// ribbon sections data
var ribbon = [],
point1 = new Point(startx, starty),
point2 = new Point(startx, starty),
point3 = null,
color = Math.round(random(0, 360)),
delay = 0;

// buils ribbon sections
while (true)
{
if (stop <= 0) break;stop--;

movex = Math.round((Math.random() * 1 - 0.2) * this._options.horizontalSpeed);
movey = Math.round((Math.random() * 1 - 0.5) * (this._height * 0.25));

point3 = new Point();
point3.copy(point2);

if (dir === "right")
{
point3.add(movex, movey);
if (point2.x >= max) break;
} else
if (dir === "left")
{
point3.subtract(movex, movey);
if (point2.x <= min) break;
}
// point3.clampY( 0, this._height );

ribbon.push({ // single ribbon section
point1: new Point(point1.x, point1.y),
point2: new Point(point2.x, point2.y),
point3: point3,
color: color,
delay: delay,
dir: dir,
alpha: 0,
phase: 0 });


point1.copy(point2);
point2.copy(point3);

delay += 4;
color += this._options.colorCycleSpeed;
}
this._ribbons.push(ribbon);
},

// Draw single section
_drawRibbonSection: function (section)
{
if (section)
{
if (section.phase >= 1 && section.alpha <= 0)
{
return true; // done
}
if (section.delay <= 0)
{
section.phase += 0.02;
section.alpha = Math.sin(section.phase) * 1;
section.alpha = section.alpha <= 0 ? 0 : section.alpha;
section.alpha = section.alpha >= 1 ? 1 : section.alpha;

if (this._options.animateSections)
{
var mod = Math.sin(1 + section.phase * Math.PI / 2) * 0.1;

if (section.dir === "right")
{
section.point1.add(mod, 0);
section.point2.add(mod, 0);
section.point3.add(mod, 0);
} else {
section.point1.subtract(mod, 0);
section.point2.subtract(mod, 0);
section.point3.subtract(mod, 0);
}
section.point1.add(0, mod);
section.point2.add(0, mod);
section.point3.add(0, mod);
}
} else
{section.delay -= 0.5;}

var s = this._options.colorSaturation,
l = this._options.colorBrightness,
c = "hsla(" + section.color + ", " + s + ", " + l + ", " + section.alpha + " )";

this._context.save();

if (this._options.parallaxAmount !== 0)
{
this._context.translate(0, this._scroll * this._options.parallaxAmount);
}
this._context.beginPath();
this._context.moveTo(section.point1.x, section.point1.y);
this._context.lineTo(section.point2.x, section.point2.y);
this._context.lineTo(section.point3.x, section.point3.y);
this._context.fillStyle = c;
this._context.fill();

if (this._options.strokeSize > 0)
{
this._context.lineWidth = this._options.strokeSize;
this._context.strokeStyle = c;
this._context.lineCap = "round";
this._context.stroke();
}
this._context.restore();
}
return false; // not done yet
},

// Draw ribbons
_onDraw: function ()
{
// cleanup on ribbons list to rtemoved finished ribbons
for (var i = 0, t = this._ribbons.length; i < t; ++i)
{
if (!this._ribbons[i])
{
this._ribbons.splice(i, 1);
}
}

// draw new ribbons
this._context.clearRect(0, 0, this._width, this._height);

for (var a = 0; a < this._ribbons.length; ++a) // single ribbon
{
var ribbon = this._ribbons[a],
numSections = ribbon.length,
numDone = 0;

for (var b = 0; b < numSections; ++b) // ribbon section
{
if (this._drawRibbonSection(ribbon[b]))
{
numDone++; // section done
}
}
if (numDone >= numSections) // ribbon done
{
this._ribbons[a] = null;
}
}
// maintain optional number of ribbons on canvas
if (this._ribbons.length < this._options.ribbonCount)
{
this.addRibbon();
}
requestAnimationFrame(this._onDraw);
},

// Update container size info
_onResize: function (e)
{
var screen = screenInfo(e);
this._width = screen.width;
this._height = screen.height;

if (this._canvas)
{
this._canvas.width = this._width;
this._canvas.height = this._height;

if (this._context)
{
this._context.globalAlpha = this._options.colorAlpha;
}
}
},

// Update container size info
_onScroll: function (e)
{
var screen = screenInfo(e);
this._scroll = screen.scrolly;
} };
// export
return Factory;
});
new Ribbons();

找到canvas_ribbon配置,设置成刚才新加的js文件路径。我这里就是/js/ribbon/ribbon.js

1
2
3
vendors:
# Internal version: 1.0.0
canvas_ribbon: /js/ribbon/ribbon.js

背景彩带自定义颜色

ribbon.js文件找到以下配置段,可以修改colorSaturation colorBrightness 调整彩带颜色
还有其他配置,大家可以看一下注释的意思

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
this._options = {
// ribbon color HSL saturation amount
colorSaturation: "80%",
// ribbon color HSL brightness amount
colorBrightness: "60%",
// ribbon color opacity amount
colorAlpha: 0.65,
// how fast to cycle through colors in the HSL color space
colorCycleSpeed: 6,
// where to start from on the Y axis on each side (top|min, middle|center, bottom|max, random)
verticalPosition: "center",
// how fast to get to the other side of the screen
horizontalSpeed: 200,
// how many ribbons to keep on screen at any given time
ribbonCount: 3,
// add stroke along with ribbon fill colors
strokeSize: 0,
// move ribbons vertically by a factor on page scroll
parallaxAmount: -0.5,
// add animation effect to each ribbon section over time
animateSections: true
};

背景彩带自定义颜色

欢迎关注我的其它发布渠道